package com.chatplus.application.controller.admin.biz;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chatplus.application.common.page.PageParam;
import com.chatplus.application.controller.api.ChatItemApiController;
import com.chatplus.application.domain.entity.account.UserEntity;
import com.chatplus.application.domain.entity.chat.ChatHistoryEntity;
import com.chatplus.application.domain.entity.chat.ChatItemEntity;
import com.chatplus.application.domain.entity.chat.ChatModelEntity;
import com.chatplus.application.domain.entity.chat.ChatRoleEntity;
import com.chatplus.application.domain.request.admin.ChatHistoryQueryRequest;
import com.chatplus.application.domain.request.admin.ChatItemQueryRequest;
import com.chatplus.application.domain.response.ChatHistoryDetailResponse;
import com.chatplus.application.domain.response.ChatRoleDetailResponse;
import com.chatplus.application.domain.response.PlusPageResponse;
import com.chatplus.application.domain.response.admin.ChatHistoryQueryResponse;
import com.chatplus.application.domain.response.admin.ChatItemQueryResponse;
import com.chatplus.application.service.account.UserService;
import com.chatplus.application.service.chat.ChatHistoryService;
import com.chatplus.application.service.chat.ChatItemService;
import com.chatplus.application.service.chat.ChatModelService;
import com.chatplus.application.service.chat.ChatRoleService;
import com.chatplus.application.web.basecontroller.BaseController;
import com.google.common.collect.Lists;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.time.Instant;
import java.util.List;

@RestController
@RequestMapping("/api/admin/chat")
@Tag(name = "用户会话管理API", description = "用户会话管理API")
public class ChatItemAdminApiController extends BaseController {

    private final ChatItemService chatItemService;
    private final ChatHistoryService chatHistoryService;
    private final ChatModelService chatModelService;
    private final UserService userService;
    private final ChatRoleService chatRoleService;
    private final ChatItemApiController chatItemApiController;

    public ChatItemAdminApiController(ChatItemService chatItemService,
                                      ChatHistoryService chatHistoryService,
                                      ChatModelService chatModelService,
                                      UserService userService,
                                      ChatRoleService chatRoleService,
                                      ChatItemApiController chatItemApiController) {
        this.chatItemService = chatItemService;
        this.chatHistoryService = chatHistoryService;
        this.chatModelService = chatModelService;
        this.userService = userService;
        this.chatRoleService = chatRoleService;
        this.chatItemApiController = chatItemApiController;
    }

    @PostMapping("/list")
    @Operation(summary = "后台获取用户对话列表")
    public PlusPageResponse<ChatItemQueryResponse> list(@RequestBody ChatItemQueryRequest plusPageRequest) {
        PageParam pageParam = new PageParam(plusPageRequest.getPage(), plusPageRequest.getPageSize());
        LambdaQueryWrapper<ChatItemEntity> queryWrapper = Wrappers.<ChatItemEntity>lambdaQuery();
        List<String> createdAt = plusPageRequest.getCreatedAt();
        if (CollUtil.isNotEmpty(createdAt) && createdAt.size() == 2) {
            Instant startTime = DateUtil.beginOfDay(DateUtil.parse(createdAt.get(0), DatePattern.NORM_DATE_PATTERN)).toInstant();
            Instant endTime = DateUtil.endOfDay(DateUtil.parse(createdAt.get(1), DatePattern.NORM_DATE_PATTERN)).toInstant();
            queryWrapper.ge(ChatItemEntity::getCreatedAt, startTime).le(ChatItemEntity::getCreatedAt, endTime);
        }
        if (plusPageRequest.getUserId() != null) {
            queryWrapper.eq(ChatItemEntity::getUserId, plusPageRequest.getUserId());
        }
        if (StringUtils.isNotEmpty(plusPageRequest.getTitle())) {
            queryWrapper.like(ChatItemEntity::getTitle, plusPageRequest.getTitle());
        }
        queryWrapper.orderByDesc(ChatItemEntity::getCreatedAt);
        Page<ChatItemEntity> pageDTO = chatItemService.page(pageParam.toPage(), queryWrapper);
        List<ChatItemEntity> chatItemList = pageDTO.getRecords();
        if (CollUtil.isEmpty(chatItemList)) {
            return new PlusPageResponse<>(plusPageRequest.getPage(), plusPageRequest.getPageSize(), 0, 0, Lists.newArrayList());
        }
        List<ChatItemQueryResponse> responseList = chatItemList.stream().map(item -> {
            Long userId = item.getUserId();
            String chatId = item.getChatId();
            ChatItemQueryResponse response = new ChatItemQueryResponse();
            UserEntity userEntity = userService.getById(item.getUserId());
            response.setUsername(userEntity.getUsername());
            response.setUserId(userId);
            response.setChatId(chatId);
            response.setTitle(item.getTitle());
            ChatModelEntity chatModelEntity = chatModelService.getById(item.getModelId());
            if (chatModelEntity != null) {
                response.setModel(chatModelEntity.getValue());
            } else {
                response.setModel("模型已删除:" + item.getModelId());
            }
            List<ChatHistoryEntity> chatHistoryList = chatHistoryService.getChatContextHistoryList(userId, chatId);
            // 获取tokens总和
            response.setToken(chatHistoryList.stream().mapToLong(ChatHistoryEntity::getTokens).sum());
            response.setMsgNum(chatHistoryList.size());
            response.setCreatedAt(item.getCreatedAt().toEpochMilli() / 1000);
            // role设置
            ChatRoleEntity chatRoleEntity = chatRoleService.getById(item.getRoleId());
            if (chatRoleEntity != null) {
                ChatRoleDetailResponse roleResponse = new ChatRoleDetailResponse();
                roleResponse.setName(chatRoleEntity.getName());
                roleResponse.setIcon(chatRoleEntity.getIcon());
                response.setRole(roleResponse);
            }
            return response;
        }).toList();
        return new PlusPageResponse<>(pageParam.getCurrent(), pageParam.getSize()
                , pageDTO.getPages(), pageDTO.getTotal(), responseList);
    }

    @PostMapping("/message")
    @Operation(summary = "后台获取用户对话列表")
    public PlusPageResponse<ChatHistoryQueryResponse> list(@RequestBody ChatHistoryQueryRequest plusPageRequest) {
        PageParam pageParam = new PageParam(plusPageRequest.getPage(), plusPageRequest.getPageSize());
        LambdaQueryWrapper<ChatHistoryEntity> queryWrapper = Wrappers.<ChatHistoryEntity>lambdaQuery();
        List<String> createdAt = plusPageRequest.getCreatedAt();
        if (CollUtil.isNotEmpty(createdAt) && createdAt.size() == 2) {
            Instant startTime = DateUtil.beginOfDay(DateUtil.parse(createdAt.get(0), DatePattern.NORM_DATE_PATTERN)).toInstant();
            Instant endTime = DateUtil.endOfDay(DateUtil.parse(createdAt.get(1), DatePattern.NORM_DATE_PATTERN)).toInstant();
            queryWrapper.ge(ChatHistoryEntity::getCreatedAt, startTime).le(ChatHistoryEntity::getCreatedAt, endTime);
        }
        if (plusPageRequest.getUserId() != null) {
            queryWrapper.eq(ChatHistoryEntity::getUserId, plusPageRequest.getUserId());
        }
        if (StringUtils.isNotBlank(plusPageRequest.getContent())) {
            queryWrapper.like(ChatHistoryEntity::getContent, plusPageRequest.getContent());
        }
        queryWrapper.orderByDesc(ChatHistoryEntity::getCreatedAt);
        // TODO: 2024/3/1 模型查询 待优化
        if (StringUtils.isNotBlank(plusPageRequest.getModel())) {
            List<Long> modelIdList = chatModelService.list(Wrappers.<ChatModelEntity>lambdaQuery().like(ChatModelEntity::getValue, plusPageRequest.getModel()))
                    .stream().map(ChatModelEntity::getId).toList();
            if (CollUtil.isEmpty(modelIdList)) {
                return new PlusPageResponse<>(plusPageRequest.getPage(), plusPageRequest.getPageSize(), 0, 0, Lists.newArrayList());
            }
            List<ChatItemEntity> chatItemList = chatItemService.list(Wrappers.<ChatItemEntity>lambdaQuery().in(ChatItemEntity::getModelId, modelIdList));
            if (CollUtil.isEmpty(chatItemList)) {
                return new PlusPageResponse<>(plusPageRequest.getPage(), plusPageRequest.getPageSize(), 0, 0, Lists.newArrayList());
            }
            queryWrapper.in(ChatHistoryEntity::getChatId, chatItemList.stream().map(ChatItemEntity::getChatId).toList());
        }
        Page<ChatHistoryEntity> pageDTO = chatHistoryService.page(pageParam.toPage(), queryWrapper);
        List<ChatHistoryEntity> chatItemList = pageDTO.getRecords();
        if (CollUtil.isEmpty(chatItemList)) {
            return new PlusPageResponse<>(plusPageRequest.getPage(), plusPageRequest.getPageSize(), 0, 0, Lists.newArrayList());
        }
        List<ChatHistoryQueryResponse> responseList = chatItemList.stream().map(item -> {
            Long userId = item.getUserId();
            String chatId = item.getChatId();
            ChatHistoryQueryResponse response = new ChatHistoryQueryResponse();
            UserEntity userEntity = userService.getById(item.getUserId());
            response.setId(item.getId());
            response.setUsername(userEntity.getUsername());
            response.setUserId(userId);
            response.setContent(item.getContent());
            response.setType(item.getType());
            // TODO 2024/3/1 模型查询 待优化
            ChatItemEntity chatItemEntity = chatItemService.getChatItemByChatId(chatId);
            if (chatItemEntity != null) {
                ChatModelEntity chatModelEntity = chatModelService.getById(chatItemEntity.getModelId());
                if (chatModelEntity != null) {
                    response.setModel(chatModelEntity.getValue());
                } else {
                    response.setModel("模型已删除");
                }
            }
            // TODO 2024/3/1 icon查询 待优化
            if ("prompt".equals(item.getType())) {
                response.setIcon(userEntity.getAvatar());
            } else if ("reply".equals(item.getType())) {
                ChatRoleEntity chatRoleEntity = chatRoleService.getById(item.getRoleId());
                if (chatRoleEntity != null) {
                    response.setIcon(chatRoleEntity.getIcon());
                }
            }
            // 获取tokens总和
            response.setToken(item.getTokens());
            response.setCreatedAt(item.getCreatedAt().toEpochMilli() / 1000);
            return response;
        }).toList();
        return new PlusPageResponse<>(pageParam.getCurrent(), pageParam.getSize()
                , pageDTO.getPages(), pageDTO.getTotal(), responseList);
    }

    @GetMapping("/message/remove")
    @Operation(summary = "管理员删除消息记录")
    public void removeHistory(@RequestParam(value = "id") Long id) {
        chatHistoryService.removeById(id);
    }

    @GetMapping("/remove")
    @Operation(summary = "管理员删除消息记录")
    public void removeChatItem(@RequestParam(value = "chat_id") String chatId) {
        chatHistoryService.remove(Wrappers.<ChatHistoryEntity>lambdaQuery().eq(ChatHistoryEntity::getChatId, chatId));
        chatItemService.remove(Wrappers.<ChatItemEntity>lambdaQuery().eq(ChatItemEntity::getChatId, chatId));
    }

    @GetMapping("/history")
    @Operation(summary = "管理员获取消息历史记录")
    public List<ChatHistoryDetailResponse> history(@RequestParam(value = "chat_id") String chatId) {
        return chatItemApiController.history(chatId);
    }
}
